package com.tanhua.server.service;

import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.commons.template.OssTemplate;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Video;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.VideoVO;
import com.tanhua.dubbo.api.CommentApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VideosApi;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class VideosService {
    @Reference
    private VideosApi videosApi;
    @Reference
    private UserInfoApi userInfoApi;
    @Reference
    private CommentApi commentApi;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private FastFileStorageClient fastFileStorageClient;
    @Autowired
    private FdfsWebServer fdfsWebServer;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private VideoMQService mqService;

    //    @Cacheable(cacheNames = "video_List",key = "#userId")
    public PageResult<VideoVO> smallVideos(int page, int pagesize, Long userId) {
        //优先从Redis中查询推荐的视频列表；如果找不到，再从MongoDB里查询
        PageResult<Video> pageResult = findVideoListFromRedis(page, pagesize);
        if (pageResult == null) {
            pageResult=videosApi.findVideoList(page, pagesize, userId);
        }
        //把结果转成vo
        List<VideoVO> voList = new ArrayList<>();
        for (Video video : pageResult.getItems()) {
            VideoVO vo = new VideoVO();
            //把小视频信息封装到vo里
            BeanUtils.copyProperties(video, vo);
            vo.setId(video.getId().toHexString());
            vo.setCover(video.getPicUrl());
            vo.setSignature(video.getText());
            //封装发布人信息
            UserInfo userInfo = userInfoApi.findById(video.getUserId());
            BeanUtils.copyProperties(userInfo, vo);
            //当前用户是否点赞了
            Boolean like = redisTemplate.hasKey("video_like_" + UserHolder.getUserId() + "_" + video.getId().toHexString());
            vo.setHasLiked(like ? 1 : 0);
            //当前用户是否关注了
            Boolean focus = redisTemplate.hasKey("video_love_" + UserHolder.getUserId() + "_" + video.getId().toHexString());
            vo.setHasFocus(focus ? 1 : 0);
            voList.add(vo);
        }
        //构造返回值
        PageResult<VideoVO> voPageResult = new PageResult<>();
        BeanUtils.copyProperties(pageResult, voPageResult);
        voPageResult.setItems(voList);
        return voPageResult;
    }

    private PageResult<Video> findVideoListFromRedis(int page, int pagesize) {
        //从Redis中查询推荐的视频
        String vidStr = redisTemplate.opsForValue().get("QUANZI_VIDEO_RECOMMEND_" + UserHolder.getUserId());
        if (vidStr == null) {
            return null;
        }
        String[] vidArray = vidStr.split(",");

        //推荐的视频总数量
        int count = vidArray.length;
        //总共分了多少页
        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        //查询数据列表
        if (page > pages) {
            return null;
        }
        //计算查询的索引范围
        int start = (page - 1) * pagesize;
        int end = start + pagesize;
        if (end > count) {
            end = count - 1;
        }
        List<Long> vidList = new ArrayList<>();
        for (int i = start; i < end; i++) {
            vidList.add(Long.parseLong(vidArray[i]));
        }
        List<Video> videoList = videosApi.findByVids(vidList);

        return new PageResult<>(count, pagesize, pages, page, videoList);
    }

    //    @CacheEvict(cacheNames ="video_List",allEntries = true)
    public ResponseEntity saveVideos(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        //视频封面图上传到阿里云OSS
        String imagePath = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());
        //视频文件上传到FastDFS
        String videoName = videoFile.getOriginalFilename();
        String videoSuffix = videoName.substring(videoName.lastIndexOf(".") + 1);
        StorePath storePath = fastFileStorageClient.uploadFile(videoFile.getInputStream(), videoFile.getSize(), videoSuffix, null);
        String videoPath = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();
        //封装vo对象
        Video video = new Video();
        video.setUserId(UserHolder.getUserId());
        video.setText("好好学习，天天向上");
        video.setPicUrl(imagePath);
        video.setVideoUrl(videoPath);
        //保存到MongoDB
        String videoId = videosApi.save(video);
        //发送消息
        mqService.saveVideoMessage(videoId);

        return ResponseEntity.ok(null);
    }

    public ResponseEntity userFocus(Long followUserId) {
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //保存到mongoDB
        videosApi.userFocus(userId, followUserId);
        //缓存到redis，记录当前用户已关注了此用户
        redisTemplate.opsForValue().set("video_love_" + userId + "_" + followUserId, "1");
        return ResponseEntity.ok(null);
    }

    public ResponseEntity userUnFocus(Long followUserId) {
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //取消关注
        videosApi.userUnFocus(userId, followUserId);
        redisTemplate.delete("video_love_" + userId + "_" + followUserId);
        return ResponseEntity.ok(null);
    }

    public ResponseEntity like(String followUserId) {

        //获取当前用户的id
        Long userId = UserHolder.getUserId();
        //补全数据
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(followUserId));
        comment.setUserId(userId);
        //   评论类型：1点赞，2评论，3喜欢
        comment.setCommentType(1);
        //   评论内容：1对动态评论，2对视频评论，3对评论评论
        comment.setPubType(2);
        //保存评论，得到点赞数
        long count = commentApi.saveVideo(comment);
        //当前用户点赞，记录到redis中
        redisTemplate.opsForValue().set("video_like_" + userId + "_" + followUserId, "1");

        return ResponseEntity.ok(count);
    }

    public ResponseEntity dislike(String followUserId) {
        //获取当前用户的id
        Long userId = UserHolder.getUserId();
        //补全数据
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(followUserId));
        comment.setUserId(userId);
        //   评论类型：1点赞，2评论，3喜欢
        comment.setCommentType(1);
        //删除评论
        long count = commentApi.removeVideo(comment);
        //当前用户取消点赞，从redis中删除记录
        redisTemplate.delete("video_like_" + userId + "_" + followUserId);

        return ResponseEntity.ok(count);
    }
}
